"""
认证中间件：验证JWT Token
"""
from fastapi import Request, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from typing import Optional
from utils.jwt_utils import verify_token
from models.m import AdminUser


# HTTPBearer实例
security = HTTPBearer()


# 白名单路径（无需认证）
WHITE_LIST = [
    "/",
    "/docs",
    "/openapi.json",
    "/redoc",
    "/admin/auth/login",
    "/admin/auth/refresh",
]


async def get_current_user(request: Request) -> Optional[AdminUser]:
    """
    获取当前登录用户（依赖注入函数）
    :param request: FastAPI请求对象
    :return: 当前用户对象
    :raises: HTTPException 如果未登录或Token无效
    """
    # 检查白名单
    if request.url.path in WHITE_LIST:
        return None
    
    # 获取Authorization头
    authorization: str = request.headers.get("Authorization")
    
    if not authorization:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Not authenticated",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    # 解析Bearer Token
    try:
        scheme, token = authorization.split()
        if scheme.lower() != "bearer":
            raise ValueError("Invalid authentication scheme")
    except ValueError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    # 验证Token
    payload = verify_token(token, token_type="access")
    
    # 从数据库获取用户
    user_id = payload.get("user_id")
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token payload",
        )
    
    user = await AdminUser.get_or_none(id=user_id)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="User not found",
        )
    
    # 检查用户状态
    if user.status != 1:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="User is disabled",
        )
    
    # 将用户信息存入request.state
    request.state.user = user
    
    return user


async def check_permission(request: Request, permission_code: str) -> bool:
    """
    检查用户是否有某个权限
    :param request: FastAPI请求对象
    :param permission_code: 权限代码（如：user:create）
    :return: 是否有权限
    """
    user = request.state.user if hasattr(request.state, 'user') else None
    
    if not user:
        return False
    
    # 获取用户角色
    await user.fetch_related('role')
    role = user.role
    
    if not role or role.status != 1:
        return False
    
    # 超级管理员拥有所有权限
    if role.code == "super_admin":
        return True
    
    # 获取角色的所有资源
    await role.fetch_related('resources')
    resource_codes = [res.code for res in role.resources if res.status == 1]
    
    return permission_code in resource_codes

